home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Libraries / VideoToolbox 94.11.17 / VideoToolboxSources / PixMapToPICT.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-10  |  5.2 KB  |  130 lines  |  [TEXT/KAHL]

  1. /*
  2. PixMapToPICT.c
  3. Saves a section of a PixMap (or BitMap) as a PICT file. You may substitute a
  4. BitMap handle for the PixMap handle. You are allowed to specify the PICT's pixel
  5. size and the color table used in translating the PixMap to a PICT. If you
  6. request zero pixelSize, the PICT's pixelSize will be the same as that of your
  7. PixMap. If the supplied color table handle is NULL then the Macintosh operating
  8. system default color table for that pixel size will be used. Note that PICT
  9. files do not include a color table, and typically are displayed with a default
  10. color table. If you want to preserve the numerical value of each pixel then set
  11. pixelSize to zero (i.e. unchanged) and supply the color table of your PixMap,
  12. i.e. (**pm).pmTable.
  13.  
  14. EXAMPLE:
  15.     PixMapToPICT("image.pict",((CWindowPtr)window)->portPixMap,&window->portRect,0,NULL);
  16.  
  17. BUGS:
  18. It works if you use the current device (NEW_DEVICE set to 0), but produces a bad
  19. Picture if you ask NewGWorld to create a new device and make that the current
  20. device (NEW_DEVICE set to 1). The bad Picture seems to be compressed
  21. horizontally, and to have the wrong row length, resulting in skew due to
  22. wraparound, as though it were accessing a pixmap with the wrong pixelsize or
  23. rowlength. (The bad Picture can be saved to a file and opened, e.g., in
  24. TeachText, but still looks just as bad.) I haven't read Apple's documentation of
  25. OpenPicture(), but, at first sight, this would appear to be a bug in QuickDraw.
  26.  
  27. QUESTIONS:
  28. We're using OpenPicture() to capture a CopyBits command, nothing else. Is the
  29. resulting Picture affected by the pixelSize of the destination pixmap? Is the
  30. resulting Picture affected by the color table of the current device? These
  31. things affect the color translation that CopyBits normally performs, but it is
  32. possible that all of the CopyBits transformations are deferred until the Picture
  33. is actually drawn by DrawPicture. In that case there would be no need to worry
  34. about the destination port's pixelSize and current device used here. However,
  35. things can't be that rosy, as in that case it shouldn't matter that I've set the
  36. current device to be the new device created by NewGWorld. In that case I've
  37. found that the picSize is approximately proportional to the pixelSize of the
  38. destination GWorld. By the way, I've confirmed that all the GWorld stuff is
  39. correct by commenting out the Picture stuff and confirming that I can copy the
  40. source to destination and back faithfully.
  41.  
  42. HISTORY:
  43. 9/28/93    mike schechter wrote it, based in part on PixMapToPostScript.c
  44. 9/29/93    dgp polished it, substituting a GWorld for a CPort, 
  45.             so we can specify the pixel size and color table.
  46. 10/2/93    dgp    added pixelSize and colorTable arguments.
  47. 9/5/94 dgp removed assumption in printf's that int==short.
  48. */
  49. #define NEW_DEVICE 0
  50. #define DEBUG 0
  51.  
  52. #include "VideoToolbox.h"
  53. #include <Errors.h>
  54.  
  55. void PixMapToPICT(char *filename,PixMap **pm,Rect *rectPtr
  56.     ,int pixelSize,ColorTable **cTable)
  57. {
  58.     FILE *file;
  59.     long buffer[128],n,value;
  60.     int error,i;
  61.     PicHandle pic;
  62.     CGrafPtr oldPort;
  63.     GDHandle oldDevice,device;
  64.     GWorldPtr world;
  65.     GWorldFlags flags;
  66.     
  67.     Gestalt(gestaltQuickdrawVersion,&value);
  68.     if(value<gestalt32BitQD)
  69.         PrintfExit("Sorry. PixMapToPICT requires 32-bit QuickDraw.\n");
  70.     if(pixelSize==0)if((**pm).rowBytes & 0x8000)    // Pixmap or Bitmap?
  71.         pixelSize=(**pm).pixelSize;        // Pixmap
  72.     else pixelSize=1;                    // Bitmap
  73.  
  74.     // draw pixmap into a Picture
  75.     GetGWorld(&oldPort,&oldDevice);
  76.     if(NEW_DEVICE){
  77.         // Ask NewGWorld to create a device, using supplied pixelSize and cTable.
  78.         flags=0;
  79.         device=NULL;
  80.     }else{
  81.         // Use the current device. (Ignores supplied pixelSize and cTable.)
  82.         flags=noNewDevice;
  83.         device=oldDevice;
  84.     }
  85.     error=NewGWorld(&world,pixelSize,rectPtr,cTable,device,flags);
  86.     if(error==cNoMemErr || error==memFullErr)
  87.         error=NewGWorld(&world,pixelSize,rectPtr,cTable,device,flags|useTempMem);
  88.     if(error==cTempMemErr)
  89.         PrintfExit("PixMapToPICT: not enough memory; reduce rect or pixelSize.\n");
  90.     if(error)PrintfExit("PixMapToPICT: NewGWorld error %d.\n",error);
  91.     LockPixels(world->portPixMap);
  92.     SetGWorld(world,NULL);
  93.     ClipRect(rectPtr);
  94.     pic=OpenPicture(rectPtr);
  95.     CopyBits((BitMap *)*pm,(BitMap *)*world->portPixMap
  96.         ,rectPtr,rectPtr,srcCopy,NULL);
  97.     ClosePicture();
  98.     SetGWorld(oldPort,oldDevice);
  99.     if(DEBUG){
  100.         // Confirm that Picture is ok. Just for debugging.
  101.         printf("pixelSize %d\n",(int)(**world->portPixMap).pixelSize);
  102.         printf("Picture size %d\n",(int)(**pic).picSize);
  103.         EraseRect(rectPtr);
  104.         DrawPicture(pic,rectPtr);
  105.     }
  106.     DisposeGWorld(world);    
  107.     error=QDError();
  108.     if(error)PrintfExit("PixMapToPICT: QDError %d.\n",(int)QDError());
  109.     if(EmptyRect(&(*pic)->picFrame) && !EmptyRect(rectPtr))
  110.         PrintfExit("PixMapToPICT: out of memory. Reduce rect or pixelSize.\n");
  111.     
  112.     // save Picture to a file
  113.     file=fopen(filename,"wb");
  114.     if(file==NULL)PrintfExit("PixMapToPICT: Error in opening file \"%s\".\n"
  115.         ,filename);
  116.     // zero 512-byte header
  117.     for(i=0;i<128;i++)buffer[i]=0;
  118.     if(128!=fwrite(buffer,4,128,file))
  119.         PrintfExit("PixMapToPICT: Error writing header of file \"%s\".\n",filename);
  120.     n=GetHandleSize((Handle)pic);
  121.     n=(n+1)&~1L; /* round up to multiple of 2 */
  122.     HLock((Handle)pic);
  123.     if(n!=fwrite(*pic,1,n,file))
  124.         PrintfExit("PixMapToPICT: Error writing file \"%s\"\n",filename);
  125.     fclose(file);
  126.     SetFileInfo(filename,'PICT','ttxt');
  127.     KillPicture(pic);
  128. }
  129.  
  130.